﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace WebPALTT.Lib
{
    [Serializable]
    public class TestResult : ISerializable
    {
        List<Scenario> mScenarios = new List<Scenario> { };
        List<ScenarioResults> mResults = new List<ScenarioResults> { };
        DateTime mRunDate;
        string mName;
        TimeSpan mRunDuration;

        public List<Scenario> Scenarios { get { return mScenarios; } }
        public List<ScenarioResults> Results { get { return mResults; } }
        public DateTime RunDate { get { return mRunDate; } set { mRunDate = value; } }
        public string Name { get { return mName; } set { mName = value; } }
        public TimeSpan RunDuration { get { return mRunDuration; } set { mRunDuration = value; } }

        public TestResult(Scenario[] scenario, ScenarioResults[] results, DateTime runDate, string name, TimeSpan duration)
        {
            this.mScenarios.AddRange(scenario);
            this.mResults.AddRange(results);
            this.mRunDate = runDate;
            this.mName = name;
            this.mRunDuration = duration;
        }

        public TestResult(SerializationInfo info, StreamingContext ctxt)
        {
            mName = (string)info.GetValue("Name", typeof(string));
            mScenarios = (List<Scenario>)info.GetValue("Scenarios", typeof(List<Scenario>));
            mResults = (List<ScenarioResults>)info.GetValue("Results", typeof(List<ScenarioResults>));
            mRunDate = (DateTime)info.GetValue("RunDate", typeof(DateTime));
            mRunDuration = (TimeSpan)info.GetValue("Duration", typeof(TimeSpan));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("Name", mName);
            info.AddValue("Scenarios", mScenarios);
            info.AddValue("Results", mResults);
            info.AddValue("RunDate", mRunDate);
            info.AddValue("Duration", mRunDuration);
        }

        public int GetMessageCount(bool warnings = true, bool errors = true)
        {
            if (mResults == null)
                return 0;
            int count = 0;
            foreach (ScenarioResults scene in mResults)
                count += scene.GetMessageCount(warnings, errors);
            return count;
        }
    }

    [Serializable()]
    public class TestResultCollection : IList<TestResult>, ICollection<TestResult>, IEnumerable<TestResult>, ISerializable
    {
        public IEnumerator<TestResult> GetEnumerator() { return mResults.GetEnumerator(); }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return mResults.GetEnumerator(); }

        public TestResultCollection(SerializationInfo info, StreamingContext ctxt)
        {
            mResults = (List<TestResult>)info.GetValue("Results", typeof(List<TestResult>));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("Results", mResults);
        }

        List<TestResult> mResults = new List<TestResult> { };

        public TestResultCollection() { }

        public int Count { get { return mResults.Count; } }

        public bool IsReadOnly { get { return false; } }

        public TestResult this[int index] { get { return mResults[index]; } set { mResults[index] = value; } }

        public TestResult this[string name]
        {
            get
            {
                foreach (TestResult rdef in mResults)
                    if (rdef.Name.Equals(name))
                        return rdef;
                return null;
            }
            set
            {
                for (int i = 0; i < mResults.Count; i++)
                    if (mResults[i].Name.Equals(name))
                        mResults[i] = value;
            }
        }

        public void Add(TestResult item) { mResults.Add(item); }

        public void AddRange(IEnumerable<TestResult> collection) { mResults.AddRange(collection); }

        public void Clear() { mResults.Clear(); }

        public bool Contains(TestResult item) { return mResults.Contains(item); }

        public bool Contains(TestResult value, IEqualityComparer<TestResult> comparer) { return mResults.Contains(value, comparer); }

        public void CopyTo(TestResult[] array, int arrayIndex) { mResults.CopyTo(array, arrayIndex); }

        public int IndexOf(TestResult value) { return mResults.IndexOf(value); }

        public int IndexOf(string name) 
        {
            for (int i = 0; i < mResults.Count; i++)
                if (mResults[i].Name.Equals(name)) { return i; }
            return -1; 
        }

        public void Insert(int index, TestResult value) { mResults.Insert(index, value); }

        public bool Remove(TestResult value) { return mResults.Remove(value); }

        public void RemoveAt(int index) { mResults.RemoveAt(index); }
    }
}
